由於 build 完整個 Frontend Project 會不只 index.html, 和 index.js ,後端的 embed 也要進行修改。
toolgui/toolgui-web/app/build$ tree .
.
├── asset-manifest.json
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
├── robots.txt
└── static
├── css
│ ├── main.036bff31.css
│ └── main.036bff31.css.map
└── js
├── 317.406936a5.chunk.js
├── 317.406936a5.chunk.js.map
├── main.65de86a6.js
├── main.65de86a6.js.LICENSE.txt
└── main.65de86a6.js.map
資料夾底下有三類:
之所以把 Index html 和其他檔案特別拉出來而不是直接用 embed.FS 吃下整個 build folder,是因為我們之後需要支援 multipage,設計的 mulitpage url 就是 /(page-name) ,這樣就需要保留第一層的檔案。
Static folder 要用 embed.FS 吃下,以方便 http server 去 serve :
// toolgui-web/web.go
//go:embed app/build/static/*
var staticDir embed.FS
func GetStaticDir() fs.FS {
fsys, err := fs.Sub(staticDir, path.Join("app", "build"))
if err != nil {
panic(err)
}
return fsys
}
// toolgui/tgexec/web.go
mux.Handle("GET /static/", http.FileServerFS(toolguiweb.GetStaticDir()))
Index 直接用老方法 Serve
// toolgui-web/web.go
//go:embed app/build/index.html
var IndexBody string
// toolgui/tgexec/web.go
func (e *WebExecutor) handleIndex(resp http.ResponseWriter, req *http.Request) {
resp.Write([]byte(toolguiweb.IndexBody))
}
其他檔案就預先整理成一個 map,然後按名字 serve:
// toolgui-web/web.go
//go:embed app/build/*
var rootAssets embed.FS
func GetRootAssets() map[string][]byte {
entries, err := rootAssets.ReadDir(path.Join("app", "build"))
if err != nil {
panic(err)
}
files := map[string][]byte{}
for _, entry := range entries {
if entry.IsDir() {
continue
}
bs, err := rootAssets.ReadFile(path.Join("app", "build", entry.Name()))
if err != nil {
panic(err)
}
files[entry.Name()] = bs
}
return files
}
// toolgui/tgexec/web.go
func (e *WebExecutor) handleAssets(resp http.ResponseWriter, req *http.Request) {
pageName := req.PathValue("name")
body, isRootAssets := e.rootAssets[pageName]
if !isRootAssets {
resp.WriteHeader(http.StatusNotFound)
return
}
resp.Write(body)
}